package com.wing.device.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wing.common.exception.BusinessException;
import com.wing.common.utils.CodeUtil;
import com.wing.common.utils.DateUtils;
import com.wing.common.utils.JsonResult;
import com.wing.device.dao.DeviceDao;
import com.wing.device.model.entity.*;
import com.wing.device.model.request.DeviceForm;
import com.wing.device.model.response.DeviceVO;
import com.wing.dict.model.entity.DictLabel;
import com.wing.product.dao.DynamicDao;
import com.wing.product.model.entity.ProductType;
import com.wing.product.model.response.ProductTypeVO;
import com.wing.product.service.ProductTypeService;
import com.wing.purchase.model.entity.SupplierInfo;
import com.wing.purchase.model.entity.SupplierLevel;
import com.wing.purchase.service.SupplierInfoService;
import com.wing.user.feign.UserClient;
import com.wing.user.model.response.CompanyInfoVO;
import com.wing.user.model.response.DepartmentVO;
import com.wing.web.db.config.util.DynamicDataSource;
import com.wing.web.excel.DeviceExcelIn;
import com.wing.web.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 设备表-ServiceImpl
 *
 * @author
 */
@Service
@Slf4j
public class DeviceServiceImpl extends ServiceImpl<DeviceDao, Device> implements DeviceService {
    @Value("${platform.gatewayUrl}")
    private String url;

    @Autowired
    private DeviceEnclosureService deviceEnclosureService;

    @Autowired
    private DeviceTypeService deviceTypeService;

    @Autowired
    private DeviceCategoryService deviceCategoryService;

    @Autowired
    private DeviceModelService deviceModelService;

    @Autowired
    private SupplierInfoService supplierInfoService;
    @Autowired
    private DeviceBrandService deviceBrandService;
    @Autowired
    private DynamicDao dynamicDao;
    @Autowired
    private ProductTypeService productTypeService;
    @Autowired
    private UserClient userClient;

    @Override
    @Transactional
    public int add(DeviceForm deviceForm) throws Exception {

        int count = 0;String code = deviceForm.getDeviceCode();
        for (int i = 0; i < deviceForm.getAddNum(); i++) {
            if(count == 0) {
                QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
                queryWrapper.like("device_code", deviceForm.getDeviceCode())
                        .eq("status", 0);
                List<Device> list = this.list(queryWrapper);
                if(list.size() > 0){
                    Device device = list.get(list.size() - 1);
                    int dex = device.getDeviceCode().lastIndexOf("-")+1;
                    String deviceCode = device.getDeviceCode().substring(dex);
                    count = Integer.parseInt(deviceCode)+1;
                    deviceForm.setDeviceCode(code.concat("-0" + String.valueOf(count+1)));
                }else{
                    deviceForm.setDeviceCode(code.concat("-01"));
                }
            }else{
                deviceForm.setDeviceCode(code.concat("-0" + String.valueOf(count+1)));
            }
            deviceForm.setCreator(JwtUtils.getLoginUserId());
            deviceForm.setCreatorName(JwtUtils.getLoginUsername());
            deviceForm.setStatus(Device.Status.normalUse);
            count++;
            Device device = new Device();
            CopyOptions copyOptions = CopyOptions.create()
                    .setEditable(Device.class)
                    .setIgnoreError(true)
                    .setIgnoreNullValue(true);
            BeanUtil.copyProperties(deviceForm, device, copyOptions);
            if(this.save(device)){
                DeviceEnclosure deviceEnclosure = new DeviceEnclosure();
                deviceEnclosure.setDeviceId(device.getId())
                        .setEnclosureUrl(deviceForm.getEnclosureUrl());
                deviceEnclosureService.save(deviceEnclosure);
            }

/*            final String reqUri = url+"platform/device/admin/device/addDevice";
            String jsonObject = JSONUtil.toJsonStr(deviceForm);
            String tokenJson = HttpHelper.httpPost(reqUri, jsonObject);*/
            //out.println(String.format("==========================>this is response:{%s}", tokenJson));
        }

        return count;

    }


    @Override
    @Transactional
    public int save(DeviceForm deviceForm)  {
        Long creator=JwtUtils.getLoginUserId();
        String creatorName=JwtUtils.getLoginUsername();
        int count = 0;
//        String code = deviceForm.getDeviceCode();
        String suffix=deviceForm.getSuffix();

        String prefix=deviceForm.getPrefix();

        String separator=deviceForm.getSeparator();
        if (separator==null){
            separator="";
        }
        Integer startNo=deviceForm.getStartNo();
        Integer noLen=deviceForm.getNoLen();
        if (noLen==null){
            noLen=startNo.toString().length();
        }
        if (noLen<startNo.toString().length()){
            noLen=startNo.toString().length();
        }
        Integer maxSortNo=baseMapper.getMaxSortNo();
        if (maxSortNo==null){
            maxSortNo=0;
        }
        for (int i = 0; i < deviceForm.getAddNum(); i++) {

            Integer nextNo=startNo+i;
            String code="";
            if (StringUtils.isNotBlank(prefix)){
                code=prefix+code+separator;
            }
            code=code+StringUtils.leftPad(nextNo.toString(),noLen,"0");
            if (StringUtils.isNotBlank(suffix)){
                code=code+separator+suffix;
            }
            deviceForm.setSortNumber(maxSortNo+(i+1)*10);
            deviceForm.setDeviceCode(code);
            if (baseMapper.selectCount(new QueryWrapper<Device>().eq("device_code",code))>0){
                throw new BusinessException("该前缀以及起始序号生成的设备编号存在重复");
            }
            deviceForm.setCreator(creator);
            deviceForm.setCreatorName(creatorName);
            deviceForm.setStatus(Device.Status.normalUse);
            count++;
            Device device = new Device();
            CopyOptions copyOptions = CopyOptions.create()
                    .setEditable(Device.class)
                    .setIgnoreError(true)
                    .setIgnoreNullValue(true);
            BeanUtil.copyProperties(deviceForm, device, copyOptions);
            if(device.getSupplierId()!=null){
                SupplierInfo supplierInfo = supplierInfoService.getById(device.getSupplierId());
                device.setSupplierName(supplierInfo.getCorporateName());
            }
            if(this.save(device)){
                DeviceEnclosure deviceEnclosure = new DeviceEnclosure();
                deviceEnclosure.setDeviceId(device.getId())
                        .setEnclosureUrl(deviceForm.getEnclosureUrl());
                //deviceEnclosureService.save(deviceEnclosure);
            }

/*            final String reqUri = url+"platform/device/admin/device/addDevice";
            String jsonObject = JSONUtil.toJsonStr(deviceForm);
            String tokenJson = HttpHelper.httpPost(reqUri, jsonObject);*/
            //out.println(String.format("==========================>this is response:{%s}", tokenJson));
        }

        return count;

    }

    @Override
    public DeviceVO getDeviceVO(String deviceCode) {

        return baseMapper.getDeviceVO(deviceCode);
    }

    @Override
    public void updateEnclosure(Long deviceId,String enclosureUrl){
        UpdateWrapper<DeviceEnclosure> writeWrapper = new UpdateWrapper<>();
        writeWrapper.set("enclosure_url",enclosureUrl)
                .eq("device_id",deviceId);
        deviceEnclosureService.update(writeWrapper);
    }
    @Override
    public List<DeviceVO> list4app(Map<String, Object> params) {
        List<DeviceVO> deviceVOList = baseMapper.list4app(params);
        setDeviceVOListItem(deviceVOList);
        return deviceVOList;
    }

    private void setDeviceVOListItem(List<DeviceVO> deviceVOList) {
        for (DeviceVO item : deviceVOList){
            JsonResult<DepartmentVO> jsonResult = userClient.getDepartmentVOById(item.getDepartmentId());
            if(null != jsonResult && null != jsonResult.getData()) {
                item.setDepartmentName(jsonResult.getData().getName());
            }
            JsonResult<CompanyInfoVO> companyInfo = userClient.getCompanyInfo(item.getCompanyInfoId());
            if(null != companyInfo && null != companyInfo.getData()) {
                item.setEnterpriseName(companyInfo.getData().getName());
            }
        }
    }

    @Override
    public Page<DeviceVO> pageList4app(Page page, Map<String, Object> params) {
        List<DeviceVO> list = baseMapper.list4app(page, params);
        setDeviceVOListItem(list);
        page.setRecords(list);
        return page;
    }

    @Override
    public Page<DeviceVO> pageListProcess(Page page,  List<String> deviceCodes) {
        List<DeviceVO> list = baseMapper.pageListProcess(page, deviceCodes);
        page.setRecords(list);
        return page;
    }

    @Override
    public DeviceVO get4appById(Long id) {
        return baseMapper.get4appById(id);
    }

    @Autowired
    private DeviceWorkshopService deviceWorkshopService;

    @Override
    public void importExcel(List<DeviceExcelIn> list) {
        //判断SKU编号是否有重复
        List newList = list.stream().map(DeviceExcelIn::getDeviceCode).distinct().collect(Collectors.toList());
        if(newList.size() != list.size()){
            throw new BusinessException("设备编码重复！");
        }
        int i = 1;
        for(DeviceExcelIn item:list){
            i++;
            if(StringUtils.isBlank(item.getName())){
                throw new BusinessException(300, "第"+i+"行设备名称未输入数据");
            }
            if(StringUtils.isBlank(item.getDeviceCode())){
                throw new BusinessException(300, "第"+i+"行设备编码未输入数据");
            }
            if(StringUtils.isBlank(item.getPropertyCode())){
                throw new BusinessException(300, "第"+i+"行资产编码未输入数据");
            }
            if(StringUtils.isBlank(item.getCompanyInfoName())){
                throw new BusinessException(300, "第"+i+"行所属企业未输入数据");
            }
            Device device = new Device();
            device.setName(item.getName());
            device.setDeviceCode(item.getDeviceCode());
            device.setPropertyCode(item.getPropertyCode());
            device.setDepreciationDuration(item.getDepreciationDuration());
            device.setDepreciationPrice(item.getDepreciationPrice());
            device.setInspectCycle(item.getInspectCycle());
            device.setMaintenanceCycle(item.getMaintenanceCycle());
            // 时间处理
            device.setDepreciationTime(DateUtils.convertToLocalDateTime(item.getDepreciationTime()));
            device.setInspectTime(DateUtils.convertToLocalDateTime(item.getInspectTime()));
            device.setInspectNextTime(DateUtils.convertToLocalDateTime(item.getInspectNextTime()));
            device.setMaintenanceTime(DateUtils.convertToLocalDateTime(item.getMaintenanceTime()));
            device.setMaintenanceNextTime(DateUtils.convertToLocalDateTime(item.getMaintenanceNextTime()));


            if(item.getSupplierName()!=null){
                SupplierInfo supplierInfo = supplierInfoService.getOne(new LambdaQueryWrapper<SupplierInfo>().eq(SupplierInfo::getStatus,SupplierInfo.Status.pass).eq(SupplierInfo::getCorporateName, item.getSupplierName()));
                device.setSupplierName(supplierInfo.getCorporateName());
                device.setSupplierId(supplierInfo.getId());
            }
            // 所属企业
            JsonResult<CompanyInfoVO> departmentByName = userClient.getCompanyByName(item.getCompanyInfoName());
            if(departmentByName.getData()!=null){
                device.setCompanyInfoName(departmentByName.getData().getName());
                device.setCompanyInfoId(departmentByName.getData().getId());
            }

            // 设备分类
            if(StringUtils.isNotBlank(item.getDeviceCategory())){
                DeviceCategory deviceCategory = deviceCategoryService.getOne(new LambdaQueryWrapper<DeviceCategory>().eq(DeviceCategory::getName, item.getDeviceCategory()));
                if(deviceCategory!=null){
                    device.setCategoryId(deviceCategory.getId());
                }else {
                    DeviceCategory DeviceCategoryFrom = new DeviceCategory();
                    DeviceCategoryFrom.setName(item.getDeviceCategory());
                    DeviceCategoryFrom.setParentId(-1l);
                    deviceCategoryService.save(DeviceCategoryFrom);
                    device.setCategoryId(DeviceCategoryFrom.getId());
                }
            }

            // 设备类型
            if(StringUtils.isNotBlank(item.getDeviceType())){
                ProductType productType = productTypeService.getOne(new LambdaQueryWrapper<ProductType>().eq(ProductType::getName, item.getDeviceType())) ;
                if(productType!=null){
                    device.setDeviceType(productType.getId());
                }else {
//                    DeviceType DeviceTypeFrom = new DeviceType();
//                    DeviceTypeFrom.setName(item.getDeviceType());
//                    String code=deviceTypeService.getCode();
//                    deviceType.setCode("M"+code);
//                    deviceType.setNo(Integer.valueOf(code));
//                    deviceTypeService.save(DeviceTypeFrom);
//                    device.setDeviceType(DeviceTypeFrom.getId());
                }
            }

            // 设备型号
            if(StringUtils.isNotBlank(item.getDeviceModel())){
                DeviceModel deviceModel = deviceModelService.getOne(new LambdaQueryWrapper<DeviceModel>().eq(DeviceModel::getName, item.getDeviceModel()));
                if(deviceModel!=null){
                    device.setDeviceModelId(deviceModel.getId());
                    device.setReferenceUrl(deviceModel.getReferenceUrl());
                    device.setDirectionUrl(deviceModel.getDirectionUrl());
                    device.setOtherUrl(deviceModel.getOtherUrl());
                    device.setDeviceAppendix(deviceModel.getDeviceAppendix());

                }else {
//                    DeviceModel deviceModelFrom = new DeviceModel();
//                    deviceModelFrom.setName(item.getDeviceModel());
//                    deviceModelFrom.setDeviceType(item.getDeviceType());
//                    deviceModelService.save(deviceModelFrom);
//                    device.setDeviceModelId(deviceModelFrom.getId());
                }
            }
            // 设备品牌
            if(StringUtils.isNotBlank(item.getDeviceBrandName())){
                DeviceBrand deviceBrand = deviceBrandService.getOne(new LambdaQueryWrapper<DeviceBrand>().eq(DeviceBrand::getName, item.getDeviceBrandName()));
                if(deviceBrand != null){
                    device.setDeviceBrandId(deviceBrand.getId());
                    device.setDeviceBrandName(item.getDeviceBrandName());
                }else{
                    Integer maxNo = dynamicDao.getMaxNo("dev_device_brand");
                    String code = CodeUtil.getCode(maxNo);
                    DeviceBrand brand = new DeviceBrand();
                    brand.setCode("PP" + code);
                    brand.setNo(Integer.valueOf(code));
                    brand.setName(item.getDeviceBrandName());
                    deviceBrandService.save(brand);
                    device.setDeviceBrandId(brand.getId());
                    device.setDeviceBrandName(item.getDeviceBrandName());
                }
            }
            //车间
            //获取所有车间信息
            Page<DeviceWorkshop> pg = new Page<>(1, 999);
            QueryWrapper<DeviceWorkshop> queryWrapper2 = new QueryWrapper<>();

            IPage<DeviceWorkshop> list2 = deviceWorkshopService.getBaseMapper().selectPage(pg, queryWrapper2);
            List<DeviceWorkshop> deviceWorkshopList = list2.getRecords();
            DeviceWorkshop result1 = deviceWorkshopList.stream()
                    .filter(provinces -> provinces.getName().equals(item.getDeviceWorkshopName()))
                    .findFirst()
                    .orElse(null);
            if(result1!=null){
                device.setWorkshopId(result1.getId());
            }

            //匹配对应部门信息
            JsonResult treeData = userClient.getTreeData(null, null);
            Object data = treeData.getData();
            List<String> departList = new ArrayList<>();
            if (data instanceof List) {
                extractNames(data, departList, item.getDepartName());
            }
            if(departList.size()>0){
                device.setDepartmentId(Long.valueOf(departList.get(0)));
            }
            device.setCreator(JwtUtils.getLoginUserId());
            device.setCreatorName(JwtUtils.getLoginUsername());
            device.setStatus(Device.Status.normalUse);
            baseMapper.insert(device);
        }
    }

    @Override
    public JsonResult getMaxModel(Long devModelId) {
        Long maxCode = baseMapper.getMaxModel(devModelId);
        if(Objects.nonNull(maxCode)){
            return JsonResult.success(maxCode);
        }else{
            return JsonResult.success(0);
        }
    }



    public void extractNames(Object data, List<String> departList,String departName) {
        if (data instanceof List) {
            @SuppressWarnings("unchecked")
            List<LinkedHashMap<String, Object>> dataList = (List<LinkedHashMap<String, Object>>) data;

            for (LinkedHashMap<String, Object> item : dataList) {
                // 提取当前节点的 name
                if (item.containsKey("name")) {
                    String name = (String) item.get("name");
                    String value = (String) item.get("value");
                    if(departName.equals(name)){
                        departList.add(value);
                    }
                }

                // 递归处理 children
                Object children = item.get("children");
                if (children instanceof List) {
                    extractNames(children, departList,departName);
                }
            }
        }
    }
}
